import { Intersection, Object3D, Raycaster, Vector2, Event, Vector3 } from 'three'
import { antiShake } from '../Util/common'
import { PROJECTION } from '../Util/static'
import { CqkjMap } from './CqkjMap'



export class MouseHandler {
  intersects: Array<Intersection<Object3D<Event>>> = []
  get target() {
    return this.intersects[0]?.object
  }

  readonly location = new Vector3()
  active = true
  constructor(map: CqkjMap) {
    const raycaster = new Raycaster()
    raycaster.layers.set(1)
    const { renderer, scene } = map

    const anchor = new Vector2()

    const onMouseMove = antiShake((e) => {
      if (this.active) {
        const { camera } = map
        anchor.x = e.offsetX / renderer.domElement.offsetWidth * 2 - 1
        anchor.y = -(e.offsetY / renderer.domElement.offsetHeight) * 2 + 1

        raycaster.setFromCamera(anchor, camera)

        const intersects = raycaster.intersectObjects(scene.children, true)

        const target = intersects[0]?.object

        if (this.target !== target) {
          this.target?.userData.onMouseLeave?.()
          target?.userData.onMouseEnter?.()
        }

        this.intersects = intersects
        const point = intersects[0]?.point
        if (point) {
          PROJECTION.unproject(this.location.copy(point))
          map.elements.forEach(e => e.show && e.onMouseMove?.())
        }
      }
    })

    renderer.domElement.addEventListener('mousemove', onMouseMove)
    renderer.domElement.addEventListener('click', () => {
      this.target?.userData.onClick?.()
    })
    renderer.domElement.addEventListener('mouseleave', () => {
      this.target?.userData.onMouseLeave?.()
      this.intersects = []
    })
  }
}
